#include "my_global.h"
#include "mysql.h"
#include <string.h>
#include "db.h"
#include "ecmfs_cmn.h"
#include "configfile.h"
#define WITH_DB 1
#define WITHOUT_DB 0

#define DEBUG 0

#if DEBUG
#define DEBUG_PRINTF(fmt , args...) \
    printf(fmt , ##args );
#define DEBUG_LOG(fmt , args...) \
    printf("[%s][%d] " fmt "\n" , __FUNCTION__, __LINE__ , ##args );
#else
#define DEBUG_LOG(fmt , args... ) 
#define DEBUG_PRINTF(fmt , args... ) 
#endif



typedef struct db_t_ {
db_type_t db_type;
const char *dropTable[MASTER_TABLE_MAX]; 
const char *createTable[MASTER_TABLE_MAX];
const char *pkey[FOREIGN_KEY_MAX];
const char *alterTable[MASTER_TABLE_MAX];
} db_t;

db_conn_t db;
db_t dbinfo;

extern config_file_t *cfile;
void conn_info()
{
  printf("MySQL client version: %s\n",
             mysql_get_client_info());
}

void finish_with_error(void)
{
  if (db.con) {  
    fprintf(stderr, "%s\n", mysql_error(db.con));
    closeConn();
  }
  exit(1);        
}
  

void closeConn(void)
{
  if (db.con) {
    DEBUG_LOG("closing db %s", db.name);
    mysql_close(db.con);
    db.con = NULL;
  }
}
const char  *dropTableArray[MASTER_TABLE_MAX] = {
    /*01*/ "DROP TABLE IF EXISTS node",
    /*02*/ "DROP TABLE IF EXISTS node_op",
    /*04*/ "DROP TABLE IF EXISTS fs_core_node_map",
    /*05*/ "DROP TABLE IF EXISTS fs_edge_node_map",
    /*06*/ "DROP TABLE IF EXISTS core_edge_map",
    /*08*/ "DROP TABLE IF EXISTS user_edge_node_map",
    /*09*/ "DROP TABLE IF EXISTS user_core_node_map",
    /*10*/ "DROP TABLE IF EXISTS fs_group",
    /*11*/ "DROP TABLE IF EXISTS fs_group_users_map",
    /*13*/ "DROP TABLE IF EXISTS fsgrp_file_map",
    /*14*/ "DROP TABLE IF EXISTS session",
    /*12*/ "DROP TABLE IF EXISTS file",
    /*03*/ "DROP TABLE IF EXISTS file_system",
    /*07*/ "DROP TABLE IF EXISTS user",
    };

const char  *pkeyAutoIncrement[MASTER_TABLE_MAX] = {
    /*01*/ "ALTER TABLE node ADD node_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*02*/ "ALTER TABLE node_op ADD node_op_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*03*/ "ALTER TABLE file_system ADD fs_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*04*/ "ALTER TABLE fs_core_node_map ADD fs_core_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*05*/ "ALTER TABLE fs_edge_node_map ADD fs_edge_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*06*/ "ALTER TABLE core_edge_map ADD fs_core_edge_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*07*/ "ALTER TABLE user ADD user_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*08*/ "ALTER TABLE user_edge_node_map ADD user_edge_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*09*/ "ALTER TABLE user_core_node_map ADD user_core_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*10*/ "ALTER TABLE fs_group ADD fs_grp_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*11*/ "ALTER TABLE fs_group_users_map ADD fg_user_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*12*/ "ALTER TABLE file ADD file_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*13*/ "ALTER TABLE fsgrp_file_map ADD file_fsgrp_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    /*14*/ "ALTER TABLE session ADD session_id INT PRIMARY KEY AUTO_INCREMENT FIRST;",
    };

const char *createTableArray[MASTER_TABLE_MAX]     = {
/*01 MASTER_TABLE_Node, */
"CREATE TABLE node ( "
"	node_id              INT NOT NULL AUTO_INCREMENT,"
"	node_name            VARCHAR( 100 ),"
"	node_url             VARCHAR( 100 ),"
"	node_ip              VARCHAR( 32 ),"
"	node_port            INT,"
"	node_desc            VARCHAR( 100 ),"
"	num_sessions         INT,"
"	cpu_usage            INT,"
"	CONSTRAINT Pk_node PRIMARY KEY ( node_id )"
" );",
/*02 MASTER_TABLE_NodeOpType, */
"CREATE TABLE node_op ( "
"	node_op_id           INT NOT NULL AUTO_INCREMENT,"
"	node_id              INT NOT NULL,"
"	node_type            INT,"
"	node_pub_key         VARCHAR( 4096 ),"
"	node_priv_key        VARCHAR( 4096 ),"
"	CONSTRAINT Pk_node_op PRIMARY KEY ( node_op_id )"
" );",
/*03 MASTER_TABLE_HostedFileSystem, */

"CREATE TABLE file_system ( "
"	fs_id                INT NOT NULL AUTO_INCREMENT,"
"	max_size             INT,"
"	max_users            INT,"
"	used_size            INT,"
"	num_users            INT,"
"	num_sessions         INT,"
"	cpu_usage            INT,"
"	CONSTRAINT Pk_file_system PRIMARY KEY ( fs_id )"
" );",
/*04 MASTER_TABLE_FSCoreNodeMap, */
"CREATE TABLE fs_core_node_map ( "
"	fs_core_id           INT NOT NULL AUTO_INCREMENT,"
"	core_node_id         INT NOT NULL,"
"	fs_hosted_path       VARCHAR(200),"
"	num_sessions     INT,"
"	fs_id                INT NOT NULL,"
"	CONSTRAINT Pk_fs_core_node_map PRIMARY KEY ( fs_core_id )"
" );",
/*05 MASTER_TABLE_FSEdgeNodeMap, */
"CREATE TABLE fs_edge_node_map ( "
"	fs_edge_id           INT NOT NULL AUTO_INCREMENT,"
"	edge_node_id           INT NOT NULL,"
"	num_sessions     INT,"
"	fs_id                INT NOT NULL,"
"	CONSTRAINT Pk_fs_edge_node_map PRIMARY KEY ( fs_edge_id )"
" );",
/*06 MASTER_TABLE_CoreEdgeMap, */
"CREATE TABLE core_edge_map ( "
"	fs_core_edge_id     INT NOT NULL AUTO_INCREMENT,"
"	fs_map_edge_id          INT NOT NULL,"
"	fs_map_core_id          INT NOT NULL,"
"	CONSTRAINT Pk_core_edge_map PRIMARY KEY ( fs_core_edge_id )"
" );",
/*07 MASTER_TABLE_User, */
"CREATE TABLE user ( "
"	user_id              INT NOT NULL AUTO_INCREMENT,"
"	user_name            VARCHAR( 100 ),"
"	user_descr           VARCHAR( 100 ),"
"	user_login           VARCHAR( 100 ),"
"	user_password        VARCHAR( 100 ),"
"	user_pub_key         VARCHAR( 4096 ),"
"	user_status          INT,"
"	user_role            INT,"
"	user_perms           INT,"
"	CONSTRAINT Pk_user PRIMARY KEY ( user_id )"
" );",
/*08 MASTER_TABLE_UserFSEdgeMap, */
"CREATE TABLE user_edge_node_map ( "
"	user_edge_id         INT NOT NULL AUTO_INCREMENT,"
"	user_map_fs_edge_id           INT NOT NULL,"
"	user_id              INT NOT NULL,"
"	CONSTRAINT Pk_user_edge_node_map PRIMARY KEY ( user_edge_id )"
" );",
/*09 MASTER_TABLE_UserFSCoreMap, */
"CREATE TABLE user_core_node_map ( "
"	user_core_id         INT NOT NULL AUTO_INCREMENT,"
"	user_map_fs_core_id           INT NOT NULL,"
"	user_id              INT NOT NULL,"
"	CONSTRAINT Pk_user_core_node_map PRIMARY KEY ( user_core_id )"
" );",
/*10 MASTER_TABLE_FSGroup, */
"CREATE TABLE fs_group ( "
"	fs_grp_id        INT NOT NULL AUTO_INCREMENT,"
"	fs_grp_name      VARCHAR( 100 ),"
"	fs_pub_key       VARCHAR( 4096 ),"
"	fs_priv_key      VARCHAR( 4096 ),"
"	fileperms_id     INT,"
"	num_files        INT,"
"	fs_id            INT NOT NULL,"
"	CONSTRAINT Pk_fs_group PRIMARY KEY ( fs_grp_id )"
" );",
/*11 MASTER_TABLE_FSGrpUserMap, */
"CREATE TABLE fs_group_users_map ( "
"	fg_user_id           INT NOT NULL AUTO_INCREMENT,"
"	fg_id                INT NOT NULL,"
"	user_id              INT NOT NULL,"
"	user_perm            INT,"
"	CONSTRAINT Pk_fs_group_users_map PRIMARY KEY ( fg_user_id )"
" );",
/*12 MASTER_TABLE_File, */
"CREATE TABLE file ( "
"	file_id              INT NOT NULL AUTO_INCREMENT,"
"	file_name            VARCHAR( 100 ),"
"	fle_description      VARCHAR( 100 ),"
"	file_size            INT,"
"	file_path            VARCHAR( 100 ),"
"	file_modification_seq_id INT,"
"	file_num_chunks      INT,"
"	file_chunk_size      INT,"
"	CONSTRAINT Pk_file PRIMARY KEY ( file_id )"
" );",
/*13 MASTER_TABLE_FSGroupFileMap, */
"CREATE TABLE fsgrp_file_map ( "
"	file_fsgrp_id        INT NOT NULL AUTO_INCREMENT,"
"	fg_id                INT NOT NULL,"
"	file_id              INT NOT NULL,"
"	CONSTRAINT Pk_fsgrp_file_map PRIMARY KEY ( file_fsgrp_id )"
" );",
/*14 MASTER_TABLE_Session, */
"CREATE TABLE session ( "
"	session_id           INT NOT NULL AUTO_INCREMENT,"
"	user_id              INT NOT NULL,"
"	fs_id                INT NOT NULL,"
"	login_status         INT,"
"	session_key          VARCHAR( 4096 ),"
"	CONSTRAINT Pk_session PRIMARY KEY ( session_id )"
" );",
        };

const char  *alterTableArray[FOREIGN_KEY_MAX] = {
/* 01 node_op->node*/ 
"ALTER TABLE node_op ADD FOREIGN KEY fk_node_op_node ( node_id ) REFERENCES node( node_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 02 fs_edge_node->node */ 
"ALTER TABLE fs_edge_node_map ADD FOREIGN KEY fk_fs_edge_node_map_node_op ( node_op_id ) REFERENCES node_op( node_op_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 03 fs_edge_node->filesystem*/ 
"ALTER TABLE fs_edge_node_map ADD FOREIGN KEY fk_fs_edge_node_map ( fs_id ) REFERENCES file_system( fs_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 04 fs_core_node->node */ 
"ALTER TABLE fs_core_node_map ADD FOREIGN KEY fk_fs_core_node_map ( fs_id ) REFERENCES file_system( fs_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 05 fs_core_node->filesystem*/ 
"ALTER TABLE fs_core_node_map ADD FOREIGN KEY fk_fs_core_node_map_node_op ( node_op_id ) REFERENCES node_op( node_op_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 06 core_edge_map->fs_core_node*/ 
"ALTER TABLE core_edge_map ADD FOREIGN KEY fk_core_edge_map_core_node_op ( fs_map_core_id ) REFERENCES fs_core_node_map( fs_core_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 07 core_edge_map->fs_edge_node*/ 
"ALTER TABLE core_edge_map ADD FOREIGN KEY fk_core_edge_map_edge_node_op ( fs_map_edge_id ) REFERENCES fs_edge_node_map( fs_edge_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 08 user_edge_node_map->edge_node */ 
"ALTER TABLE user_edgenode_map ADD FOREIGN KEY fk_user_edgenode_map ( user_map_fs_edge_id ) REFERENCES fs_edge_node_map( fs_edge_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 09 user_edge_node_map->user */ 
"ALTER TABLE user_edgenode_map ADD FOREIGN KEY fk_user_edgenode_map_user ( user_id ) REFERENCES user( user_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 10 user_core_node_map->core_node*/ 
"ALTER TABLE user_core_node_map ADD FOREIGN KEY fk_user_core_node_map ( user_map_fs_core_id ) REFERENCES fs_core_node_map( fs_core_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 11 user_core_node_map->user */ 
"ALTER TABLE user_core_node_map ADD FOREIGN KEY fk_user_core_node_map_user ( user_id ) REFERENCES user( user_id ) ON DELETE CASCADE ON UPDATE CASCADE;",


/* 12 file_group->filesystem*/ 
"ALTER TABLE file_group ADD FOREIGN KEY fk_file_group_file_system ( fs_id ) REFERENCES file_system( fs_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 13 file_group_users->file_group*/ 
"ALTER TABLE file_group_users_map ADD FOREIGN KEY fk_file_group_users_map_fgid ( fg_id ) REFERENCES file_group( file_group_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 14 file_filegroup_map->filegroup */ 
"ALTER TABLE fsgrp_file_map ADD FOREIGN KEY fk_fsgrp_file_map_file_group ( fg_id ) REFERENCES file_group( file_group_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 15 file_filegroup_map->file*/ 
"ALTER TABLE fsgrp_file_map ADD FOREIGN KEY fk_fsgrp_file_map_file ( file_id ) REFERENCES file( file_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 16 session->user*/ 
"ALTER TABLE session ADD FOREIGN KEY fk_session_user ( user_id ) REFERENCES user( user_id ) ON DELETE CASCADE ON UPDATE CASCADE;",

/* 17 session->file_system*/ 
"ALTER TABLE session ADD FOREIGN KEY fk_session_file_system ( fs_id ) REFERENCES file_system( fs_id ) ON DELETE CASCADE ON UPDATE CASCADE;",
    };

#define MYSQL_DB_HOST cfile->db_host
#define MYSQL_DB_LOGIN cfile->db_login
#define MYSQL_DB_PASSWORD cfile->db_password
#define MYSQL_DB_NAME cfile->db_name
void init_params(db_type_t db_type)
{
    int i;
    db.host = MYSQL_DB_HOST;
    db.login = MYSQL_DB_LOGIN;
    db.password = MYSQL_DB_PASSWORD;
    /* BY default we create the same database 
     * on all nodes, as an optimization in future
     * we have to create seperate views for edge/master/core
     */
    if ((db_type == DB_TYPE_MASTER) ||
        (db_type == DB_TYPE_EDGE) ||
        (db_type == DB_TYPE_CORE)) {
        db.name = MYSQL_DB_NAME; 
        for (i = 0; i < MASTER_TABLE_MAX; i++)
        {
            dbinfo.createTable[i] = createTableArray[i];
            dbinfo.dropTable[i] = dropTableArray[i];
            dbinfo.pkey[i] = pkeyAutoIncrement[i];
        } 
        for (i = 0; i < FOREIGN_KEY_MAX; i++)
        {
            dbinfo.alterTable[i] = alterTableArray[i];
        }
        dbinfo.db_type = db_type;
    }
}

void createConn(int dbFlag)
{
  const char *dbName = NULL;

  if (db.con)  {
    return;
  } 

  db.con = mysql_init(NULL);

  if (db.con == NULL) 
  {
      fprintf(stderr, "%s\n", mysql_error(db.con));
      exit(1);
  }

  if (dbFlag) {
    dbName = db.name;
  }
  if (mysql_real_connect(db.con, db.host, 
          db.login, db.password, 
          dbName, 0, NULL, 0) == NULL) 
  {
      finish_with_error();
      db.con = NULL;
      exit(1);
  }  
  return;  
}

int createDb()
{  
  char statement[100];

  createConn(WITHOUT_DB);
  if (!db.con) {
    fprintf(stderr, "No connection");
    return -1;
  }
    
  DEBUG_LOG("createDatabase %s", db.name);
  memset(statement, 0, 100);
  strcpy(statement, "CREATE DATABASE ");
  strcat(statement, db.name); 
  if (mysql_query(db.con, statement)) 
  {
      finish_with_error();
  }

  closeConn();
  return 0;
}

int createTables()
{
  int i;
  createConn(WITH_DB);
  if (!db.con) {
    fprintf(stderr, "No connection");
    return -1;
  }

  for (i = 0; i < MASTER_TABLE_MAX; i++)
  {    
      if (*dbinfo.dropTable[i]) {
        DEBUG_LOG("dropTable[%d] = %s", i,dbinfo.dropTable[i]);
        if (mysql_query(db.con, dbinfo.dropTable[i] )) {
            //finish_with_error();
        }
      }
  }

  for (i = 0; i < MASTER_TABLE_MAX; i++)
  {    
      if (*dbinfo.createTable[i]) {
        DEBUG_LOG("createTable[%d] = %s", i,dbinfo.createTable[i]);
        if (mysql_query(db.con, dbinfo.createTable[i] )) {
            //finish_with_error();
        }
      }
  }

  for (i = 0; i < MASTER_TABLE_MAX; i++)
  {    
      if (*dbinfo.pkey[i]) {
        DEBUG_LOG("pkey[%d] = %s", i,dbinfo.pkey[i]);
        if (mysql_query(db.con, dbinfo.pkey[i] )) {
            //finish_with_error();
        }
      }
  }

    
  for (i = 0; i < FOREIGN_KEY_MAX; i++)
  {    
      if (*dbinfo.alterTable[i]) {
        DEBUG_LOG("alterTable[%d] = %s", i,dbinfo.alterTable[i]);
        if (mysql_query(db.con, dbinfo.alterTable[i] )) {
            //finish_with_error();
        }
      }
  }

  DEBUG_LOG("Databases Created");
  closeConn();
  return 0;
}

db_ret_t open_db()
{
  if ((dbinfo.db_type != DB_TYPE_MASTER) &&
      (dbinfo.db_type != DB_TYPE_EDGE) &
      (dbinfo.db_type != DB_TYPE_CORE)) {
      return DB_ERROR;
  }

  createConn(WITH_DB);
  if (!db.con) {
    fprintf(stderr, "No connection");
    return DB_ERROR;
  }

   return DB_SUCCESS;
}

db_ret_t close_db()
{
    if ((dbinfo.db_type != DB_TYPE_MASTER) &&
        (dbinfo.db_type != DB_TYPE_EDGE) &
        (dbinfo.db_type != DB_TYPE_CORE)) {
        return DB_ERROR;
    }
    closeConn();
    return DB_SUCCESS;

}

db_ret_t del_user(char *user)
{
    char statement[100];
    if ((dbinfo.db_type != DB_TYPE_MASTER) &&
        (dbinfo.db_type != DB_TYPE_EDGE) &
        (dbinfo.db_type != DB_TYPE_CORE)) {
        return DB_ERROR;
    }

    DEBUG_LOG("add_user %s", user);
    memset(statement, 0, 100);
    snprintf(statement, 100,
        "DELETE FROM user WHERE user_login='%s'", 
        user);
    if (mysql_query(db.con, statement)) 
    {
        finish_with_error();
    }
    return DB_SUCCESS;
}

db_ret_t add_user(char *user, char *password)
{
    char statement[100];
    if ((dbinfo.db_type != DB_TYPE_MASTER) &&
        (dbinfo.db_type != DB_TYPE_EDGE) &
        (dbinfo.db_type != DB_TYPE_CORE)) {
        return DB_ERROR;
    }

    DEBUG_LOG("add_user %s %s", user, password);
    memset(statement, 0, 100);
    snprintf(statement, 100, "INSERT INTO user(user_login, user_password)" 
    "VALUES( '%s' ,'%s')", user, password);
    if (mysql_query(db.con, statement)) 
    {
        finish_with_error();
    }
    return DB_SUCCESS;
}




db_ret_t add_node(node_info_t *node)
{
    int id;
    char statement[100];
    if ((dbinfo.db_type != DB_TYPE_MASTER) &&
        (dbinfo.db_type != DB_TYPE_EDGE) &
        (dbinfo.db_type != DB_TYPE_CORE)) {
        return DB_ERROR;
    }

    DEBUG_LOG("add_node %s %d", node->node_ip, node->node_port);
    memset(statement, 0, 100);
    snprintf(statement, 100, "INSERT INTO node(node_name, node_ip, node_port)" 
    "VALUES( '%s' ,'%s', '%d')", node->node_name, node->node_ip,
                            node->node_port);
    if (mysql_query(db.con, statement)) 
    {
        finish_with_error();
    }

    id = mysql_insert_id(db.con);

    memset(statement, 0, 100);
    snprintf(statement, 100, "INSERT INTO node_op(node_id, node_type)" 
    "VALUES( '%d', '%d')", id, node->node_type);
    if (mysql_query(db.con, statement)) 
    {
        finish_with_error();
    }


    return DB_SUCCESS;

}

db_ret_t check_user(char *user)
{
    char statement[100];
    MYSQL_RES *result;
    MYSQL_FIELD *field;
    int num_fields;
    int i;
    db_ret_t ret = DB_ERROR;
    MYSQL_ROW row;
    int row_index=0;
    
    if ((dbinfo.db_type != DB_TYPE_MASTER) &&
        (dbinfo.db_type != DB_TYPE_EDGE) &
        (dbinfo.db_type != DB_TYPE_CORE)) {
        return DB_ERROR;
    }

    DEBUG_LOG("check_user %s ...", user);
    memset(statement, 0, 100);
    snprintf(statement, 100, 
	"SELECT * FROM user WHERE user_login='%s'",
	 user);
    if (mysql_query(db.con, statement)) 
    {
        DEBUG_LOG(" ...Error In Query %s", user);  
        finish_with_error();
    }

    result = mysql_store_result(db.con);
  
    if (result == NULL) 
    {
        DEBUG_LOG(" ... notfound %s", user);        
        return DB_ERROR;
    }

    num_fields = mysql_num_fields(result);
    if (num_fields == 0)
    {
        DEBUG_LOG(" ... notfound %s", user);        
        return DB_ERROR;
    }

    while ((row = mysql_fetch_row(result))) 
    { 
      for(i = 0; i < num_fields; i++) 
      { 
          field = mysql_fetch_field(result);
          //if (row_index == 0) {
                //printf("%d **%s --> %s \n",i, field->name,
                    //row[i]?row[i]:"?");
                
                if (strcmp(field->name,  "user_login") == 0) {
                    if  ((row[i]) &&
                         (strcmp(row[i], user) == 0)) {
                        DEBUG_LOG(" ... found %s !!", user);        
                        ret = DB_SUCCESS;
                        break;
                        }
                }
          //}      
      } 

      row_index++;
    }
  
    mysql_free_result(result);
  
    return ret;
}



db_ret_t check_node(char *node)
{
    char statement[100];
    MYSQL_RES *result;
    MYSQL_FIELD *field;
    int num_fields;
    int i;
    db_ret_t ret = DB_ERROR;
    MYSQL_ROW row;
    int row_index=0;
    
    if ((dbinfo.db_type != DB_TYPE_MASTER) &&
        (dbinfo.db_type != DB_TYPE_EDGE) &
        (dbinfo.db_type != DB_TYPE_CORE)) {
        return DB_ERROR;
    }

    DEBUG_LOG("check_node %s ...", node);
    memset(statement, 0, 100);
    snprintf(statement, 100, 
	"SELECT * FROM node WHERE node_name='%s'",
	 node);
    if (mysql_query(db.con, statement)) 
    {
        DEBUG_LOG(" ...Error In Node Query %s", node);  
        finish_with_error();
    }

    result = mysql_store_result(db.con);
  
    if (result == NULL) 
    {
        DEBUG_LOG(" ... node not found %s", node);        
        return DB_ERROR;
    }

    num_fields = mysql_num_fields(result);
    if (num_fields == 0)
    {
        DEBUG_LOG(" ... node not found %s", node);        
        return DB_ERROR;
    }

    while ((row = mysql_fetch_row(result))) 
    { 
      for(i = 0; i < num_fields; i++) 
      { 
          field = mysql_fetch_field(result);
          //if (row_index == 0) {
                //printf("%d **%s --> %s \n",i, field->name,
                    //row[i]?row[i]:"?");
                
                if (strcmp(field->name,  "node_name") == 0) {
                    if  ((row[i]) &&
                         (strcmp(row[i], node) == 0)) {
                        DEBUG_LOG(" ... found %s !!", node);        
                        ret = DB_SUCCESS;
                        break;
                        }
                }
          //}      
      } 

      row_index++;
    }
  
    mysql_free_result(result);
  
    return ret;
}

db_ret_t get_nodes(node_details_t **nodes,
                   int *node_count)
{
    char statement[100];
    MYSQL_RES *result;
    MYSQL_FIELD *field;
    int num_fields;
    int i;
    db_ret_t ret = DB_ERROR;
    MYSQL_ROW row;
    int row_index=0;
    node_details_t *n=NULL;
    int fn_index, fip_index, fp_index, fnid_index;
    int j;
    if ((dbinfo.db_type != DB_TYPE_MASTER) &&
        (dbinfo.db_type != DB_TYPE_EDGE) &
        (dbinfo.db_type != DB_TYPE_CORE)) {
        return DB_ERROR;
    }


    memset(statement, 0, 100);
    snprintf(statement, 100, 
	"SELECT DISTINCT node_name, node_id,node_ip, node_port FROM node");
    if (mysql_query(db.con, statement)) 
    {
        DEBUG_LOG("%s ...Error In Node Query ", __FUNCTION__);  
        finish_with_error();
    }

    result = mysql_store_result(db.con);
  
    if (result == NULL) 
    {
        DEBUG_LOG("%s  ... node not found ", __FUNCTION__);        
        return DB_ERROR;
    }

    num_fields = mysql_num_fields(result);
    if (num_fields == 0)
    {
        DEBUG_LOG("%s ... node not found ", __FUNCTION__);        
        return DB_ERROR;
    }
    n = (node_details_t *)malloc(5*sizeof(node_details_t));
    j = 0;
    while ((row = mysql_fetch_row(result))) 
    { 
      DEBUG_LOG("%s  node %d:", __FUNCTION__,row_index);  
      if (row_index == 0) 
      {
          for(i = 0; i < num_fields; i++) 
          { 
              field = mysql_fetch_field(result);
    
                if (strcmp(field->name,  "node_name") == 0) {
                    fn_index = i;
                    DEBUG_PRINTF("%10s | ",field->name);
                } else 
                if (strcmp(field->name,  "node_ip") == 0) {
                    fip_index = i;
                    DEBUG_PRINTF("%10s | ",field->name);
                } else 
                if (strcmp(field->name,  "node_port") == 0) {
                    fp_index = i;
                    DEBUG_PRINTF("%10s | ",field->name);
                }
                if (strcmp(field->name,  "node_id") == 0) {
                    fnid_index = i;
                    DEBUG_PRINTF("%10s | ",field->name);
                }  
           }
      }
      else
      {
            DEBUG_PRINTF("\n"); 
            if  (row[fn_index]) {
                strncpy(n[j].node_name, row[fn_index], 32);
                DEBUG_PRINTF("%10s | ",row[fn_index]);
            }
            
            if  (row[fip_index]) {
                strncpy(n[j].node_ip, row[fip_index], 32);
                DEBUG_PRINTF("%10s | ",row[fip_index]);
            }
            
            if  (row[fp_index]) {
                n[j].port = atoi(row[fp_index]);
                DEBUG_PRINTF("%10d | ",n[j].port);
            }
            
            if  (row[fnid_index]) {
                n[j].node_id = atoi(row[fnid_index]);
                DEBUG_PRINTF("%10d | ",n[j].node_id);
            }
      }
      DEBUG_PRINTF("\n");

      if (row_index != 0) j++;
      row_index++;
    }
    
    *nodes = n;
    *node_count = j;
    mysql_free_result(result);
  
    return ret;
}

